package gui;

import java.io.BufferedWriter;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.ArrayList;

import protocol.generic.AbstractProtocolManager;
import protocol.generic.ProtocolEventHandler;
import protocol.self.NewYaimProtocolManager;
import protocol.xmpp.XMPPProtocolManager;

import EventHandler.JambiEventHandler;
import EventHandler.YaimEventHandler;

import com.trolltech.qt.core.QFile;
import com.trolltech.qt.core.QIODevice;
import com.trolltech.qt.core.QModelIndex;
import com.trolltech.qt.core.QObject;
import com.trolltech.qt.core.QTextStream;
import com.trolltech.qt.core.Qt;
import com.trolltech.qt.gui.QCloseEvent;
import com.trolltech.qt.gui.QDialog;
import com.trolltech.qt.gui.QHeaderView;
import com.trolltech.qt.gui.QIcon;
import com.trolltech.qt.gui.QMessageBox;
import com.trolltech.qt.gui.QPixmap;
import com.trolltech.qt.gui.QStandardItem;
import com.trolltech.qt.gui.QStandardItemModel;
import com.trolltech.qt.gui.QAbstractItemView.SelectionBehavior;

public class AccountManager extends QDialog{
	Ui_AccountManager aui=new Ui_AccountManager();
	Ui_ModifyAccount mui=new Ui_ModifyAccount();
	QStandardItemModel model;
	int rowNum;					//to record which line is actived at the time being
	ArrayList<String> arr;		//read in all the account lines recorded
	MainWindow mainWindow;		//keep an object of MainWindow to know which managers are added already
	
	/*********************************	constructor	*********************************************
	 * 1.setup the accountmanager window
	 * 2.setup the model in the accountmanager
	 * 3.read data from account.txt in resource folder and associate the model with those data.
	 * 4.setup the connections in this accountmanager window
	 ********************************************************************************************/
	public AccountManager(MainWindow mw){
		super(mw);
		mainWindow=mw;
		aui.setupUi(this);
		
		//******************************	set the table header	****************************
		model=new QStandardItemModel(0, 3,this);
		model.setHeaderData(0, Qt.Orientation.Horizontal, "Open");
        model.setHeaderData(1, Qt.Orientation.Horizontal, "User Name");
        model.setHeaderData(2, Qt.Orientation.Horizontal, "Protocol");
        aui.tableView.horizontalHeader().setResizeMode(QHeaderView.ResizeMode.Stretch);
        
        //******************************	set the table model		****************************
        arr=new ArrayList<String>();
        ArrayList<String> managerIds=new ArrayList<String>();
        for(AbstractProtocolManager ma : mainWindow.protocolManagers)
        	managerIds.add(ma.getUserID().split("@")[0]);
		QFile file=new QFile("classpath:resources/account.txt");
        if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadWrite)))
            return;
        QTextStream in=new QTextStream(file);
        while (!in.atEnd()) {
            String line = in.readLine();
            arr.add(line);
            QStandardItem col01;
            //**************************	if the account is already log on, the table shows ON	*************
            if(managerIds.contains(line.split("	")[0]))
            	col01=new QStandardItem(new QIcon(new QPixmap("classpath:resources/log-out.png")),"On");
            else
            	col01=new QStandardItem(new QIcon(new QPixmap("classpath:resources/log-in.png")),"Off");
            
    		QStandardItem col02=new QStandardItem(line.split("	")[0]);
    		String protocolName=line.split("	")[2];
    		QStandardItem col03=new QStandardItem(protocolName);
    		if(protocolName.equalsIgnoreCase("gtalk"))
    			col03.setIcon(new QIcon(new QPixmap("classpath:resources/google-talk.png")));
    		else if(protocolName.equalsIgnoreCase("Jabber"))
    			col03.setIcon(new QIcon(new QPixmap("classpath:resources/jabber.png")));
    		else
    			col03.setIcon(new QIcon(new QPixmap("classpath:resources/aim.png")));
    		col01.setEditable(false);
    		col02.setEditable(false);
    		col03.setEditable(false);
    		ArrayList<QStandardItem> row=new ArrayList<QStandardItem>();
    		row.add(col01);
    		row.add(col02);
    		row.add(col03);
    		model.appendRow(row);
        }
        file.close();
        
        aui.tableView.setSelectionBehavior(SelectionBehavior.SelectRows);
        aui.tableView.setModel(model);
        aui.tableView.doubleClicked.connect(this, "tableModelClicked(QModelIndex)");
        aui.tableView.clicked.connect(this, "setActivated(QModelIndex)");
        aui.deleteButton.clicked.connect(this,"deleteAccount()");
        aui.closeButton.clicked.connect(this,"close()");
        aui.addButton.clicked.connect(this, "addAccount()");
        aui.modifyButton.clicked.connect(this, "modifyAccount()");
        this.show();
	}
	
	//**********************	to record which row is actived	**********************
	public void setActivated(QModelIndex index){
		rowNum=index.row();
	}
	
	/**********************	table view's double clicked handler	*****************************
	 * To control which account should be set on
	 * 
	 * if one item in the first column of the table is double clicked, the account of
	 * this row will be set on || off.
	 * And the Icon will be also changed.
	 * All the operation on account's on || off will be reflected in the buddylist at once
	 ****************************************************************************************/
	public void tableModelClicked(QModelIndex index){
		if(index.column()!=0) return;
		QStandardItem item=model.itemFromIndex(index); 
		if(item.text().equalsIgnoreCase("On")){
			QStandardItem temp=new QStandardItem(new QIcon(new QPixmap("classpath:resources/log-in.png")),"Off");
			model.setItem(index.row(), index.column(), temp);
			aui.tableView.setModel(model);
			
			//***************************	to log off	*************************************************
			String toDelete=arr.get(index.row()).split("	")[0];
			for(int i=0;i<mainWindow.protocolManagers.size();i++){
				if(mainWindow.protocolManagers.get(i).getUserID().split("@")[0].equalsIgnoreCase(toDelete)){
					mainWindow.protocolManagers.get(i).close();
////					mainWindow.threads.get(i).stop();
////					mainWindow.threads.remove(i);
					mainWindow.protocolManagers.remove(i);
				}
			}
			mainWindow.updateBuddyList();
		}
		else{
			QStandardItem temp=new QStandardItem(new QIcon(new QPixmap("classpath:resources/log-out.png")),"On");
			model.setItem(index.row(), index.column(), temp);
			aui.tableView.setModel(model);
			
			//****************************	to log on	***********************************************
			String ss[]=arr.get(index.row()).split("	");
			AbstractProtocolManager manager;
			if(ss[2].equalsIgnoreCase("Yaim")){
				manager = new NewYaimProtocolManager(ss[2],ss[0],ss[1],ss[4],Integer.parseInt(ss[5]));
				YaimEventHandler handler=new YaimEventHandler();
				manager.setEventHandler(handler);
			}
			else{
				manager = new XMPPProtocolManager(ss[2],ss[0],ss[1],ss[3],ss[4],Integer.parseInt(ss[5]));
				JambiEventHandler handler = new JambiEventHandler();
				manager.setEventHandler(handler);
			}
			/**/
			
			mainWindow.protocolManagers.add(manager);
			try {
				mainWindow.login();
////				Thread.sleep(3000);
			}catch (InterruptedException e1) {
				e1.printStackTrace();
			}catch (Exception e) {
				e.printStackTrace();
				QMessageBox.critical(this, "login failed", "Cannot login");
				mainWindow.protocolManagers.remove(manager);
				return;
			}
/*
			if(!manager.getProtocol().equalsIgnoreCase("yaim"))
				mainWindow.updateBuddyList();
			
			QPixmap pixmap=new QPixmap();
			try {
				pixmap.loadFromData(manager.getAvatar(manager.getUserID()));
			} catch (Exception e) {
				return;
			}
			mainWindow.ui.iconButton.setIcon(new QIcon(pixmap));
	*/		
		}
	}
	
	/******************************	delete button's handler	***********************************
	 * To delete a account.
	 * 
	 * In this method, the account in the 'rowNum' row, which has been recorded active before,
	 * will be removed from the account.txt and the table view.
	 ******************************************************************************************/
	public void deleteAccount(){
		model.removeRow(rowNum);
		QFile file=new QFile("classpath:resources/account.txt");
        file.remove();
        arr.remove(rowNum);
        
        //I don't know how to create a new file in QT,so I do it in java IO
        File myFile = new File("bin/resources/account.txt");
        try {
			myFile.createNewFile();
			BufferedWriter bw = new BufferedWriter(new FileWriter(myFile));
			for(String aline : arr){
	        	bw.write(aline+"\n");
	        }
			bw.flush();
			bw.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	/************************************	Add button's handler	***************************************
	 * To add a account.
	 * 
	 * Once the add button is clicked, a new configation dialog will be showed, and it will ask you 
	 * to fill some blanks of the account you want to create.
	 * If the save is clicked in the end, the account information will be added in the acount.txt
	 * and the table view.
	 * If the cancel button is clicked, the dialog will be closed.
	 ******************************************************************************************************/
	public void addAccount(){
		QDialog addAccount=new QDialog(mainWindow);
		mui.setupUi(addAccount);
		mui.protocolBox.addItem(new QIcon(new QPixmap("classpath:resources/google-talk.png")), "Gtalk");
		mui.protocolBox.addItem(new QIcon(new QPixmap("classpath:resources/jabber.png")), "Jabber");
		mui.protocolBox.addItem(new QIcon(new QPixmap("classpath:resources/aim.png")), "Yaim");
		mui.protocolBox.activated.connect(this,"protocolSetted(String)");
		mui.protocolBox.activated.emit("Gtalk");
		mui.cancelButton.clicked.connect(addAccount, "close()");
		mui.saveButton.clicked.connect(addAccount, "close()");
		mui.saveButton.clicked.connect(this, "save()");
		addAccount.show();
	}
	
	/******************	protocolBox's handler in the "addAccount()" method	************************
	 * To switch among the protocols' default configation.
	 * 
	 * Once the protocolBox's one item is selected, some blanks in the configation dialog will be
	 * changed into the default values, which are featured in the protocol.
	 ***********************************************************************************************/
	void protocolSetted(String current){
		if(current.equalsIgnoreCase("Gtalk")){
			mui.domainEdit.show();
			mui.label_4.show();
			mui.domainEdit.setText("gmail.com");
			mui.ServerEdit.setText("talk.google.com");
			mui.PortEdit.setText("5222");
		}
		else if(current.equalsIgnoreCase("Jabber")){
			mui.domainEdit.show();
			mui.label_4.show();
			mui.domainEdit.clear();
			mui.ServerEdit.clear();
			mui.PortEdit.setText("5222");
		}
		else if(current.equalsIgnoreCase("Yaim")){
			mui.domainEdit.hide();
			mui.label_4.hide();
			mui.ServerEdit.clear();
		}
	}
	
	/******************************	modify button's handler ******************************** 
	 * To modify the account selected
	 * 
	 * similar as the addAccount() method.
	 ***************************************************************************************/
	public void modifyAccount(){
		
	}
	
	/******************	save button's handler in the "addAccount()" method	************************
	 * To save the account information in the configation into account.txt, and put it in the table 
	 * view.
	 ***********************************************************************************************/
	public void save(){
		String username=mui.usernameEdit.text();
		String pwd=mui.passwordEdit.text();
		String protocol=mui.protocolBox.currentText();
		String domain=mui.domainEdit.text();
		if(domain.equalsIgnoreCase("")) domain="domain";
		String host=mui.ServerEdit.text();
		int port=Integer.parseInt(mui.PortEdit.text());
		QFile file=new QFile("classpath:resources/account.txt");
        if (!file.open(new QIODevice.OpenMode(QIODevice.OpenModeFlag.ReadWrite)))
            return;
        QTextStream in=new QTextStream(file);
        in.readAll();
        System.out.println(in.atEnd());
        in.writeString(username+"	"+pwd+"	"+protocol+"	"+domain+"	"+host+"	"+port+"\n");
        file.close();
        String aline=username+"	"+pwd+"	"+protocol+"	"+domain+"	"+host+"	"+port;
        arr.add(aline);
        
        QStandardItem row01=new QStandardItem(new QIcon(new QPixmap("classpath:resources/log-in.png")),"Off");
		QStandardItem row02=new QStandardItem(username);
		QStandardItem row03=new QStandardItem(protocol);
		ArrayList<QStandardItem> row=new ArrayList<QStandardItem>();
		row.add(row01);
		row.add(row02);
		row.add(row03);
		model.appendRow(row);
	}
	
	@Override
	public void closeEvent(QCloseEvent event) {
		super.closeEvent(event);
		for(QObject object : this.children())
			object.dispose();
	}
}
